describe("Ajax", function(){

    var xhr,
        requests,
        callback,
        options,
        obj,
        data;

    describe("get", function(){

        beforeEach(function(){

            xhr = sinon.useFakeXMLHttpRequest();
            requests = [];
            xhr.onCreate = function(xhr){requests.push(xhr)};
            callback = sinon.spy();
            options = ajax.optionsCreate("http://en.wikipedia.org", "" , "/wiki/Ukraine");
            obj = {
                "Calling code": "+380",
                "Area Total": "603,628 km2"
            };

        });

        afterEach(function(){

            xhr.restore();

        });

        it ("callback should be called", function(){

            ajax.get(options, callback);
            requests[0].respond(200, {"Content-Type": "application/json"},
                '{"Calling code": "+380", "Area Total": "603,628 km2"}');

            expect(callback).toHaveBeenCalled();
            expect(callback).toHaveBeenCalledWith(obj);

        });

        it ("the urls have to be the same", function(){

            ajax.get(options, callback);
            requests[0].respond(200, {"Content-Type": "application/json"},
                '{"Calling code": "+380", "Area Total": "603,628 km2"}');

            expect(requests[0].url).toBe("http://en.wikipedia.org/wiki/Ukraine");

        });

    });

    describe("create", function(){

        beforeEach(function(){

            xhr = sinon.useFakeXMLHttpRequest();
            requests = [];
            xhr.onCreate = function(xhr){requests.push(xhr)};
            callback = sinon.spy();

            obj = {
                "Calling code": "+380",
                "Area Total": "603,628 km2"
            }

            data = {
                "Capital": "Kiev",
                "Official languages": "Ukrainian"
            }

            options = ajax.optionsCreate("http://en.wikipedia.org", data , "/wiki/Ukraine");

        });

        afterEach(function(){

            xhr.restore();

        });

        it ("callback should be called ", function(){

            ajax.create(options, callback);
            requests[0].respond(200, {"Content-Type": "application/json"},
                '{"Calling code": "+380", "Area Total": "603,628 km2"}');

            expect(callback).toHaveBeenCalled();
            expect(callback).toHaveBeenCalledWith(obj);

        });

        it ("should put the data to server", function(){

            ajax.create(options, callback);
            requests[0].respond(200, {"Content-Type": "text/html"},
                "someId");

            expect(callback).toHaveBeenCalledWith("someId");
        });

    });

    describe("update", function(){

        beforeEach(function(){

            xhr = sinon.useFakeXMLHttpRequest();
            requests = [];
            xhr.onCreate = function(xhr){requests.push(xhr)};
            callback = sinon.spy();

            obj = {
                "Calling code": "+380",
                "Area Total": "603,628 km2",
                "id" : "1234"
            }

            data = {
                "Calling code": "+382",
                "Area Total": "700 km2",
                "id" : "1234"
            }

            options = ajax.optionsCreate("http://en.wikipedia.org", data , "/wiki/Ukraine");

        });

        afterEach(function(){

            xhr.restore();

        });

        it ("data should be updated ", function(){

            ajax.update(options, callback);

            requests[0].respond(200, {"Content-Type": "application/json"},
                '{"id" : "1234"}');

            expect(callback).toHaveBeenCalled();
            expect(callback).toHaveBeenCalledWith({"id" : "1234"});
            expect(requests[0].requestBody).toBe(JSON.stringify(data));
        });

    });

    describe("remove", function(){

        beforeEach(function(){

            xhr = sinon.useFakeXMLHttpRequest();
            requests = [];
            xhr.onCreate = function(xhr){requests.push(xhr)};
            callback = sinon.spy();

            obj = {
                "Calling code": "+380",
                "Area Total": "603,628 km2",
                "id" : "1234"
            }

            data = {
                "id" : "1234"
            }

            options = ajax.optionsCreate("http://en.wikipedia.org", data , "/wiki/Ukraine");

        });

        afterEach(function(){

            xhr.restore();

        });

        it ("data should be replaced ", function(){

            ajax.update(options, callback);

            requests[0].respond(200, {"Content-Type": "text/html"},
                '"id" : "1234"');

            expect(callback).toHaveBeenCalled();
            expect(callback).toHaveBeenCalledWith('"id" : "1234"');

        });

    });

    describe("test cross-browser XHR", function(){

        it ("XHR for IE", function(){

            window.ActiveXObject = function(msg){

                if (msg !== "Msxml2.XMLHTTP"){

                    throw new Error ("msg is not Msxml2.XMLHTTP");

                }

                this.msg = msg;

            };

            var xhr = ajax._XmlHttpRequest("Msxml2.XMLHTTP");
            expect(xhr.msg).toBe("Msxml2.XMLHTTP");

        });

        it ("XHR for old IE ", function(){

            window.ActiveXObject = function(msg){

                if (msg === "Msxml2.XMLHTTP"){

                    throw new Error ("msg is Msxml2.XMLHTTP");

                };

                this.msg = msg;

            };

            var xhr = ajax._XmlHttpRequest("Microsoft.XMLHTTP");
            expect(xhr.msg).toBe("Microsoft.XMLHTTP");

        });

        it ("XHR for none supporter browser ", function(){

            window.ActiveXObject = function(msg){

                if (msg === "Msxml2.XMLHTTP"){

                    throw new Error ("msg is Msxml2.XMLHTTP");

                };

                if (msg === "Microsoft.XMLHTTP") {

                    throw new Error ("msg is Microsoft.XMLHTTP");

                };

            };

            var xhr = ajax._XmlHttpRequest(" IE ");

            expect(xhr.msg).toBe(undefined);

        });

        it ("XHR for normal browser ", function(){

            var xhr = ajax._XmlHttpRequest();

            expect(xhr!="undefined").toBe(true);
            expect(xhr.toString()).toBe("[object XMLHttpRequest]");

        });

    });

});
